<html>
<head><meta charset="utf-8"><title>safety of stable containers · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html">safety of stable containers</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="165660126"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165660126" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165660126">(May 14 2019 at 20:41)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span>  Hi, I just miri-checked the <code>elsa</code> crate. It provides <code>FrozenMap</code> and <code>FrozenVec</code> using <code>StableDeref</code>: i.e. these are collections you can push to while holding references to their elements, because they give you references to their dereffed elements: a <code>FrozenMap&lt;String&gt;</code> will give you <code>&amp;str</code> (which will not change on <code>.push()</code>)</p>
<p>My mutable_arena example fails miri: <a href="https://github.com/Manishearth/elsa/blob/master/examples/mutable_arena.rs#L56" target="_blank" title="https://github.com/Manishearth/elsa/blob/master/examples/mutable_arena.rs#L56">https://github.com/Manishearth/elsa/blob/master/examples/mutable_arena.rs#L56</a> (miri doesn't support examples yet, move it in tree and turn it into a binary)</p>
<p>I get this error: <a href="https://gist.github.com/Manishearth/0b053abd89fa3ad92ad00a8118923491" target="_blank" title="https://gist.github.com/Manishearth/0b053abd89fa3ad92ad00a8118923491">https://gist.github.com/Manishearth/0b053abd89fa3ad92ad00a8118923491</a></p>
<p>Talking to <span class="user-mention" data-user-id="119009">@eddyb</span> it seems like the issue is that this creates an <code>&amp;mut Vec&lt;T&gt;</code> from the unsafecell while holding on to <code>&amp;T::Deref</code>s obtained from the vec. This is supposed to be safe here because the <code>T::Deref</code>s are stored behind an allocation, so we're not actually borrowing the vec itself, and <code>Vec::push</code> does not touch these elements.</p>
<p>Is this the UB here? What's the solution moving forward for stable containers then? They're a pretty crucial thing for caching and stuff, and the alternative is basically to implement bespoke collections each time.</p>



<a name="165661833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165661833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165661833">(May 14 2019 at 21:00)</a>:</h4>
<p><span class="user-mention" data-user-id="132040">@Manish Goregaokar</span> without having seen the details yet (hopefully I will have some time for that tomorrow), this sounds like a duplicate of <a href="https://github.com/SimonSapin/rust-typed-arena/issues/26#issuecomment-484507322" target="_blank" title="https://github.com/SimonSapin/rust-typed-arena/issues/26#issuecomment-484507322">this problem</a> to me. Basically, <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=7171fd5a6366645b86772f68b1b05201" target="_blank" title="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=7171fd5a6366645b86772f68b1b05201">this is currently UB</a>:</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span>::<span class="n">with_capacity</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">v0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="o">*</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">mut</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="p">};</span><span class="w"> </span><span class="c1">// laundering the lifetime -- we take care that `v` does not reallocate, so that&#39;s okay.</span>
<span class="w">    </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">v0</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>We should probably have an issue about this.</p>



<a name="165662197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662197">(May 14 2019 at 21:03)</a>:</h4>
<p>even this weaker form is UB, for the same reason:</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span>::<span class="n">with_capacity</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">v0</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;*</span><span class="p">(</span><span class="o">&amp;</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="p">};</span><span class="w"> </span><span class="c1">// laundering the lifetime -- we take care that `v` does not reallocate, so that&#39;s okay.</span>
<span class="w">    </span><span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">v0</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p><code>Vec::push</code> currently creates a mutable ref covering all elements, which invalidates all previously created interior pointers.</p>



<a name="165662363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662363">(May 14 2019 at 21:05)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> similar, but not quite</p>



<a name="165662528"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662528" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662528">(May 14 2019 at 21:07)</a>:</h4>
<p>What we're doing is this:</p>
<div class="codehilite"><pre><span></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span>::<span class="n">new</span><span class="p">();</span><span class="w"></span>
<span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span><span class="w"></span>
<span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">v0</span><span class="w"> </span>: <span class="kp">&amp;</span><span class="kt">u32</span> <span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;*</span><span class="p">(</span><span class="o">&amp;*</span><span class="n">v</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u32</span><span class="p">)</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="n">v</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">v0</span><span class="p">;</span><span class="w"></span>
</pre></div>



<a name="165662609"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662609" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662609">(May 14 2019 at 21:08)</a>:</h4>
<p>As in, we're relying on the fact that Vec::push does not change anything except for moving the inline values (but not any allocations)</p>



<a name="165662628"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662628" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662628">(May 14 2019 at 21:08)</a>:</h4>
<p>But yes from a UB guidelines pov this is probably similar</p>



<a name="165662800"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662800" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alan Jeffrey <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662800">(May 14 2019 at 21:10)</a>:</h4>
<p><span class="user-mention" data-user-id="132040">@Manish Goregaokar</span> does reasoning about the correctness of <code>FrozenVec</code> and friends need reasoning about the <code>StableDeref</code> invariantas?</p>



<a name="165662877"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165662877" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alan Jeffrey <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165662877">(May 14 2019 at 21:11)</a>:</h4>
<p>if so, it might be difficult to persuade Miri that <code>FrozenVec</code> is OK :/</p>



<a name="165695193"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165695193" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165695193">(May 15 2019 at 08:17)</a>:</h4>
<blockquote>
<p>As in, we're relying on the fact that Vec::push does not change anything except for moving the inline values (but not any allocations)</p>
</blockquote>
<p>Hm. Your example code is accepted by Miri though, as I would have expected.</p>



<a name="165695250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165695250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165695250">(May 15 2019 at 08:18)</a>:</h4>
<p><span class="user-mention" data-user-id="128323">@Alan Jeffrey</span> why that? Of course Miri cannot show that any possible interaction is okay, but a concrete execution should be UB-free if the abstraction is correct.</p>



<a name="165695307"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165695307" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165695307">(May 15 2019 at 08:20)</a>:</h4>
<p><span class="user-mention" data-user-id="132040">@Manish Goregaokar</span> FWIW, that data structure reminds me of <a href="https://github.com/rust-lang/miri/blob/master/src/mono_hash_map.rs" target="_blank" title="https://github.com/rust-lang/miri/blob/master/src/mono_hash_map.rs">https://github.com/rust-lang/miri/blob/master/src/mono_hash_map.rs</a> ^^</p>



<a name="165695682"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165695682" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165695682">(May 15 2019 at 08:26)</a>:</h4>
<p>self-contained example: <a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=f07c6c9021435fc52dd67827635b1370" target="_blank" title="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=f07c6c9021435fc52dd67827635b1370">https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=f07c6c9021435fc52dd67827635b1370</a><br>
(not a safe API any more but that shouldnt matter when looking at a concrete execution)</p>



<a name="165698801"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165698801" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165698801">(May 15 2019 at 09:20)</a>:</h4>
<p>the reference/pointer in question points to the <code>Vec</code> itself, not its contents or so</p>



<a name="165699765"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165699765" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165699765">(May 15 2019 at 09:37)</a>:</h4>
<p>oh... this is interesting. seems to be some bad interaction with what I do for 2-phase borrows.</p>



<a name="165699887"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165699887" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165699887">(May 15 2019 at 09:39)</a>:</h4>
<p>I think this is the same issue:</p>
<div class="codehilite"><pre><span></span><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">cell</span>::<span class="n">UnsafeCell</span><span class="p">;</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">UnsafeCell</span>::<span class="n">new</span><span class="p">(</span><span class="n">vec</span><span class="o">!</span><span class="p">[]);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">x</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="o">*</span><span class="n">x</span><span class="p">.</span><span class="n">get</span><span class="p">()).</span><span class="n">push</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">x2</span><span class="p">.</span><span class="n">get</span><span class="p">()).</span><span class="n">get</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</pre></div>



<a name="165700012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165700012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165700012">(May 15 2019 at 09:41)</a>:</h4>
<p>Cc <span class="user-mention" data-user-id="116118">@Matthew Jasper</span></p>



<a name="165700090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165700090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165700090">(May 15 2019 at 09:42)</a>:</h4>
<p>specifically, this does a two-phase borrow <em>from a raw pointer</em>, which I did not think was a thing</p>



<a name="165700118"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165700118" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165700118">(May 15 2019 at 09:43)</a>:</h4>
<p>and so there are a bunch of <code>SharedReadWrite</code> that can all happily coexist, but the 2phase-borrow now adds a <code>Unique</code> right in the middle of them, which means the ones further up get invalidated once the two-phase borrow gets activated.</p>



<a name="165700316"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165700316" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165700316">(May 15 2019 at 09:46)</a>:</h4>
<p>confirmed, removing the thing that supports two-phase borrows with outstanding shared references fixes my self-contained version of the elsa testcase</p>



<a name="165701374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165701374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165701374">(May 15 2019 at 10:04)</a>:</h4>
<p>lol, I literally had this as a comment in the code:</p>
<div class="codehilite"><pre><span></span>        // TODO: With `two_phase == true`, this performs a weak reborrow for a `Unique`. That
        // can lead to some possibly surprising effects, if the parent permission is
        // `SharedReadWrite` then we now have a `Unique` in the middle of them, which &quot;splits&quot;
        // them in terms of what remains valid when the `Unique` gets used.  Is that really
        // what we want?
</pre></div>


<p>Now I know the answer: no, it is not what we want. ;)</p>



<a name="165717449"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165717449" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Alan Jeffrey <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165717449">(May 15 2019 at 14:09)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> true, the <code>StableDeref</code> invariants are only needed for proving that all safe uses of <code>FrozenVec</code> have defined behaviour, not a particular concrete execution.</p>



<a name="165721081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165721081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165721081">(May 15 2019 at 14:53)</a>:</h4>
<p><span class="user-mention" data-user-id="128323">@Alan Jeffrey</span> yes, but only to the extent that a particular impl of StableDeref should be used in a safe way</p>



<a name="165721183"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165721183" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165721183">(May 15 2019 at 14:54)</a>:</h4>
<p>Like, if StableDeref is a problem so is every other unsafe trait</p>



<a name="165721907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165721907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165721907">(May 15 2019 at 15:03)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> sorry, I'm a bit ignorant about the internals of this: does this mean the Elsa test case is fine?</p>



<a name="165721928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165721928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165721928">(May 15 2019 at 15:03)</a>:</h4>
<p>And it's Miri that needs patching?</p>



<a name="165722004"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165722004" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165722004">(May 15 2019 at 15:04)</a>:</h4>
<p>And yep! Your self contained test case is exactly what we're doing</p>



<a name="165723197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165723197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165723197">(May 15 2019 at 15:18)</a>:</h4>
<p>it does mean that this particular error is not Elsa's fault but Miri's.</p>



<a name="165723236"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165723236" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165723236">(May 15 2019 at 15:19)</a>:</h4>
<p>thanks for posting this! the only way to get decent test coverage here is to crowdsource that stuff, so I am happy to see this work :D</p>



<a name="165723261"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165723261" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165723261">(May 15 2019 at 15:19)</a>:</h4>
<p>but also this will keep me and my colleague busy for a bit while we update the implementation, documentation, formalization and proof ;)</p>



<a name="165730675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/165730675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#165730675">(May 15 2019 at 16:41)</a>:</h4>
<blockquote>
<p>specifically, this does a two-phase borrow <em>from a raw pointer</em>, which I did not think was a thing</p>
</blockquote>
<p>Well the borrow kind is marked as two-phase, but the borrow checker doesn't track the borrow (i.e. it's treated as just a read/write).</p>



<a name="166020464"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166020464" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166020464">(May 19 2019 at 12:03)</a>:</h4>
<p><span class="user-mention" data-user-id="132040">@Manish Goregaokar</span> the fixed Miri just landed in rustc, so if you could try again with the next nightly (tomorrow), that'd be great.</p>



<a name="166030399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166030399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166030399">(May 19 2019 at 16:35)</a>:</h4>
<p>Thank you!! Will do.</p>



<a name="166153127"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166153127" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166153127">(May 21 2019 at 08:40)</a>:</h4>
<p><span class="user-mention" data-user-id="132040">@Manish Goregaokar</span> </p>
<blockquote>
<p>Nightly miri now passes all of the elsa tests except for <a href="http://sync.rs" target="_blank" title="http://sync.rs">sync.rs</a> (which uses threads, which miri doesn't like because of the dynamic loading)</p>
</blockquote>
<p>awesome! Notice that threads are also themselves unsupported, the interpreter machine just has no concept of there being more than 1 stack.</p>



<a name="166153154"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166153154" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166153154">(May 21 2019 at 08:41)</a>:</h4>
<p>if you want to have Miri as part of your CI, I can help make that happen :)</p>



<a name="166178157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166178157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166178157">(May 21 2019 at 14:34)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> miri needs an --example argument for that :)</p>



<a name="166178200"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166178200" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166178200">(May 21 2019 at 14:35)</a>:</h4>
<p>oh, these are not testcases?</p>



<a name="166178270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166178270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166178270">(May 21 2019 at 14:36)</a>:</h4>
<p>hm. our cargo wrapper already is a mess :( we should somehow reuse cargo's way of selecting which binaries to build/run...</p>



<a name="166178437"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166178437" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166178437">(May 21 2019 at 14:38)</a>:</h4>
<p>I just opened an issue for this: <a href="https://github.com/rust-lang/miri/issues/739" target="_blank" title="https://github.com/rust-lang/miri/issues/739">https://github.com/rust-lang/miri/issues/739</a></p>



<a name="166178441"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166178441" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166178441">(May 21 2019 at 14:38)</a>:</h4>
<p>we could really use some help here :D</p>



<a name="166196211"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196211" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196211">(May 21 2019 at 17:57)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> I wanted to patch that but your arg parsing is kinda a mess lol</p>



<a name="166196267"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196267" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196267">(May 21 2019 at 17:57)</a>:</h4>
<p>(not necessarily blaming you, it's fine for the purpose it serves, it's just hard to extend)</p>



<a name="166196281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196281">(May 21 2019 at 17:57)</a>:</h4>
<p>Might fix it anyway later</p>



<a name="166196376"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196376" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196376">(May 21 2019 at 17:58)</a>:</h4>
<blockquote>
<p>arg parsing is kinda a mess</p>
</blockquote>
<p>that's putting it kindly^^</p>



<a name="166196435"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196435" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196435">(May 21 2019 at 17:59)</a>:</h4>
<p>but it clearly does need a rewrite, not an extension</p>



<a name="166196597"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196597" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196597">(May 21 2019 at 18:00)</a>:</h4>
<p>and you can blame me, you wouldn't be entirely wrong. ;) I didn't start it, but I went down a route of arg parsing that I knew was wrong. my only excuse is that I care a lot about the semantics Miri implements, and wanted to just get the rest done quickly.</p>



<a name="166196830"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196830" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196830">(May 21 2019 at 18:03)</a>:</h4>
<p>Maybe I'll just swap in clap</p>



<a name="166196867"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166196867" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Manish Goregaokar <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166196867">(May 21 2019 at 18:03)</a>:</h4>
<p>That's not easy either, miri also takes in normal rustc args I think</p>



<a name="166197257"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166197257" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166197257">(May 21 2019 at 18:07)</a>:</h4>
<p>yeah... the general form is <code>cargo miri &lt;optional verb&gt; &lt;args for the cargo wrapper&gt; -- &lt;args for the miri driver, which includes rustc args&gt; -- &lt;args for the application being run&gt;</code></p>



<a name="166197352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety%20of%20stable%20containers/near/166197352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/safety.20of.20stable.20containers.html#166197352">(May 21 2019 at 18:08)</a>:</h4>
<p>so we'd only want to use clap until the first <code>--</code>, and leave the rest uninterpreted. is that possible?</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>